Καλώς ορίσατε στο dotNETZone.gr - Σύνδεση | Εγγραφή | Βοήθεια
σε

 

Αρχική σελίδα Ιστολόγια Συζητήσεις Εκθέσεις Φωτογραφιών Αρχειοθήκες

VB.NET 2010 Εικόνα απο MS Access

Îåêßíçóå áðü ôï ìÝëïò AlKiS. Τελευταία δημοσίευση από το μέλος AlKiS στις 11-11-2011, 19:43. Υπάρχουν 29 απαντήσεις.
Σελίδα 1 από 2 (30 εγγραφές)   1 2 >
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  27-10-2011, 22:17 67938

    VB.NET 2010 Εικόνα απο MS Access

    Θέλω (μέσω ενός προγράμματος που έγραψα σε Visual Basic 2010 .NET) να κάνω retrieve μια εικόνα που έχω βάλει σε μια βάση δεδομένων Access.

    Έχω δοκιμάσει τα εξής 2 πράγματα, κανένα εκ των οποίων δεν δούλεψε

            pic.Image = Image.FromStream(AccessDataSet.Tables("FBICriminalsTable").Rows(0).Item("Picture"))

    και

            pic.Image = AccessDataSet.Tables("FBICriminalsTable").Rows(0).Item("Picture")


    Το πρόβλημα που μου βγάζει έιναι το εξής: Unable to cast object of type 'System.Byte[]' to type 'System.IO.Stream'

    Η βάση δεδομένων είναι Access 2007 (.accdb) και την ανοίγω με "PROVIDER=Microsoft.ACE.OLEDB.12.0;"

    Στο item "Picture" έχω πράγματι βάλη φώτο σε .jpg format και όταν ανοίγω τη βάση δεδομένων με την access, στο κουτί αυτό μου λέει: "package" και αν το κάνω 2πλο κλίκ ανοίγει η φώτο.


    Τι πρέπει να κάνω για να γίνει retrieve η εικόνα?? (όλα τα κείμενα τα βγάζει κανονικά).


  •  29-10-2011, 01:19 67955 σε απάντηση της 67938

    Απ: VB.NET 2010 Εικόνα απο MS Access

    Καμιά ιδέα κανείς???
  •  29-10-2011, 10:34 67957 σε απάντηση της 67955

    Απ: VB.NET 2010 Εικόνα απο MS Access

    Το πεδίο που αποθηκεύεις την εικόνα είναι τύπου Attachment; Αν ναι, δες λίγο σε αυτό το άρθρο, έχει και sample κώδικα σε vb.net. 


    Τάσος Καραγιάννης

    Baby debugging steps...
  •  29-10-2011, 11:42 67960 σε απάντηση της 67957

    Απ: VB.NET 2010 Εικόνα απο MS Access

    Το πεδίο μου δεν είναι attachment αλλά δεν πειράζε. Το λίνκ που μου έδωσες είναι πολύ καλό,

    Ευχαριστώ.


    Θα αφήσω για μια-δυο μέρες το τόπικ σαν μη επιλυμένο έτσι ώστε αν κάποιος ξέρει να μου πει τι ακριβώς να αλλάξω για να διαβαστεί η εικόνα, να μου πει.

    Αλλιώς θα αλλάξω εντελώς τον κώδικα και να τον κάνω σαν αυτό που είδα στο λίνκ σου για να δουλέψει.


  •  30-10-2011, 11:03 67963 σε απάντηση της 67960

    Απ: VB.NET 2010 Εικόνα απο MS Access

    AlKiS:

    Το πεδίο μου δεν είναι attachment αλλά δεν πειράζε. Το λίνκ που μου έδωσες είναι πολύ καλό,



    Άρα είναι τύπου OLE Object, σωστά; Διάβασε εδώ όπου έχει την εξής function:

    Private Shared Function ConvertToImage(ByVal imageObj As Object) As Image
        Dim ImageBytes As Byte() = CType(imageObj, Byte())
        Dim sMemory As New IO.MemoryStream(ImageBytes)
    
        Using sMemory
            Return Image.FromStream(sMemory)
        End Using
    End Function


    Τάσος Καραγιάννης

    Baby debugging steps...
  •  30-10-2011, 14:14 67965 σε απάντηση της 67963

    Απ: VB.NET 2010 Εικόνα απο MS Access

    ΩΩΩ! νομίζω ότι αυτό είναι ακριβώς αυτό που χρειάζομαι. Δεν είμαι στον υπολογιστή με το Visual Studio τώρα για να το επιβεβαιώσω αλλά είμαι 99% σίγουρος 


    Ευχαριστώ πραγματικά πολύ φίλε μου! :)


  •  30-10-2011, 22:22 67970 σε απάντηση της 67963

    Απ: VB.NET 2010 Εικόνα απο MS Access

    tasos:
    AlKiS:

    Το πεδίο μου δεν είναι attachment αλλά δεν πειράζε. Το λίνκ που μου έδωσες είναι πολύ καλό,



    Άρα είναι τύπου OLE Object, σωστά; Διάβασε εδώ όπου έχει την εξής function:

    Private Shared Function ConvertToImage(ByVal imageObj As Object) As Image
        Dim ImageBytes As Byte() = CType(imageObj, Byte())
        Dim sMemory As New IO.MemoryStream(ImageBytes)
    
        Using sMemory
            Return Image.FromStream(sMemory)
        End Using
    End Function


    Δυστυχώς μου βγάζει το εξής πρόβλημα:

    System.ArguementException: Paramater is not valid.

    at system.Drawing.Image.FromStream(Stream stream, Boolean

    useEmbeddedColorManagement, Boolean validateImageData)

    at system.DrawingImage.FromStream(Stream stream)

    at F.B.I.HQ.frmSearchEngine.ConvertToImage(object imageObj) in

    C:\.......\frmSearchEngine.vb:Line171

    at C:\......\frmSearchEngine.vb:Line 235


    Λοιπών, η σειρά 171 γράφει:

    Using sMemory


    Και η σειρά 235:

    pic.Image = ConvertToImage(AccessDataSet.Tables("FBICriminalsTable").Rows(ResultRow).Item("Picture"))
    


  •  31-10-2011, 00:01 67971 σε απάντηση της 67970

    Απ: VB.NET 2010 Εικόνα απο MS Access

    Τζάμπα ο ενθουσιασμός.. Stick out tongue

    Με λίγο search βρήκα πως το object που σου επιστρέφει το query δεν είναι το image, αλλά ένα ole object που περιέχει το image και πριν το image έχει κάποια header information. Οπότε για να παίξει πρέπει να κάνεις remove το header information για να σου μείνει η εικόνα που έχεις αποθηκεύσει. 

    Δες αυτό το άρθρο που έχει μία function που κάνει αυτή τη διαδικασία. 

    Οπότε η function πρέπει να γίνει κάπως έτσι χρησιμοποιώντας αυτή που δίνει το προηγούμενο άρθρο:

        Private Shared Function ConvertToImage(ByVal imageObj As Object) As Bitmap
            Dim ImageBytes As Byte() = CType(imageObj, Byte())
            Dim CleanImageBytes() As Byte = GetImageBytesFromOLEField(ImageBytes)
    
            Dim sMemory As New IO.MemoryStream(CleanImageBytes)
    
            Using sMemory
                Return Bitmap.FromStream(sMemory, False, True)
            End Using
        End Function

    Για το conversion από C# σε VB.NET εδώ.

    Υ.Γ. Μου έκανε εντύπωση πάντως που δεν βρήκα κάποια σχετική πληροφορία στο msdn, ενώ βρήκα κόσμο να γράφει ότι δεν υπάρχει σχετικό documentation. 


    Τάσος Καραγιάννης

    Baby debugging steps...
  •  31-10-2011, 19:11 67980 σε απάντηση της 67971

    Απ: VB.NET 2010 Εικόνα απο MS Access

    tasos:

    Τζάμπα ο ενθουσιασμός.. Stick out tongue

    Με λίγο search βρήκα πως το object που σου επιστρέφει το query δεν είναι το image, αλλά ένα ole object που περιέχει το image και πριν το image έχει κάποια header information. Οπότε για να παίξει πρέπει να κάνεις remove το header information για να σου μείνει η εικόνα που έχεις αποθηκεύσει. 

    Δες αυτό το άρθρο που έχει μία function που κάνει αυτή τη διαδικασία. 

    Οπότε η function πρέπει να γίνει κάπως έτσι χρησιμοποιώντας αυτή που δίνει το προηγούμενο άρθρο:

        Private Shared Function ConvertToImage(ByVal imageObj As Object) As Bitmap
            Dim ImageBytes As Byte() = CType(imageObj, Byte())
            Dim CleanImageBytes() As Byte = GetImageBytesFromOLEField(ImageBytes)
    
            Dim sMemory As New IO.MemoryStream(CleanImageBytes)
    
            Using sMemory
                Return Bitmap.FromStream(sMemory, False, True)
            End Using
        End Function

    Για το conversion από C# σε VB.NET εδώ.

    Υ.Γ. Μου έκανε εντύπωση πάντως που δεν βρήκα κάποια σχετική πληροφορία στο msdn, ενώ βρήκα κόσμο να γράφει ότι δεν υπάρχει σχετικό documentation. 


    Πράγματι είναι αξιοπερίεργο...

    Ευχαριστώ και πάλι, το εκτιμώ πραγματικά.

    Δυστυχώς δεν είμαι σε υπολογιστή με Visual Studio αυτή τη στιγμή. Οπότε όπως την προηγούμενη φορά, μόλις πάω θα το δω και θα απαντήσω :)


  •  01-11-2011, 21:02 67997 σε απάντηση της 67938

    Απ: VB.NET 2010 Εικόνα απο MS Access

    Το function που προτείνει ο Tasos δουλεύει (το δοκίμασα μόνο με JPG). Σίγουρα δεν καλύπτει όλες τις περιπτώσεις αφού μπορείς σε αυτού του τύπου πεδία να έχεις οτιδήποτε format (excel, word κλπ) αλλά δεν έχω κάτι καλύτερο να σου προτείνω. Επίσης Θα μπορούσες να αποφύγεις σίγουρα την μετατροπή του Byte array σε UTF7 γιά να κάνεις την δουλειά σου πιό γρήγορα.

     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
     
    Public Class Form1
        Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
            Dim ColumnName As String = "OLE_OBJ"
            Dim TableName As String = "IMAGES"
            Dim con As New OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\Vangelis\Documents\MyDB.accdb")
    
            con.Open()
    
            Dim da = New OleDb.OleDbDataAdapter("SELECT TOP 1 " & ColumnName & " FROM " & TableName, con)
            Dim dt = New DataTable
    
            da.Fill(dt)
            con.Close()
    
            If dt.Rows.Count > 0 AndAlso Not dt.Rows(0).IsNull(ColumnName) Then
                Me.BackgroundImage = Me.GetImageFromOLEField(CType(dt.Rows(0).Item(ColumnName), Byte()))
            End If
        End Sub
    
        Private Function GetImageFromOLEField(oleFieldBytes As Byte()) As Image
            Dim sFormats(4) As String
    
            sFormats(0) = "BM" ' BITMAP
            sFormats(1) = ChrW(&HFF) & ChrW(&HD8) & ChrW(&HFF) ' JPG
            sFormats(2) = ChrW(137) & "PNG" & vbCrLf & ChrW(26) & vbLf ' PNG
            sFormats(3) = "GIF8" ' GIF
            sFormats(4) = "II*" & Chr(0) ' TIFF
    
            ' Get a UTF7 Encoded string version
            Dim u8 As System.Text.Encoding = System.Text.Encoding.UTF7
            Dim strTemp As String = u8.GetString(oleFieldBytes)
    
            ' Get the first 300 characters from the string
            Dim strVTemp As String = strTemp.Substring(0, 300)
    
            Dim iPos As Integer = -1
    
            For Each s As String In sFormats
                iPos = strVTemp.IndexOf(s)
                If iPos <> -1 Then Exit For
            Next
    
            If iPos = -1 Then
                ' TODO
                Return Nothing
            End If
    
            Dim ms As New IO.MemoryStream(oleFieldBytes, iPos, oleFieldBytes.Length - iPos)
    
            Return Image.FromStream(ms)
        End Function
    End Class

    Το επόμενο παράδειγμα σου δείχνει πως εσύ μπορείς να αποθηκεύσεις τύπους ( ακόμα και δικούς σου ) σε binary μορφή, στην συγκεκριμένη περίπτωση σε Access table (ακόμα και image να είναι δεν θα διαβάζονtαι από την access σαν Package αλλά μόνο από .NET). Μετά φτιάχνει ένα Serializable Class ( με την χρήση ενός Attribute), το γράφει στην βάση και μετά το σηκώνει πάλι και βάζει το image property που έχει, σαν background image στην φόρμα. Η όλη διαδικασία λέγεται serialization - Deserialization.  Φυσικά πρέπει να βρεις έναν τρόπο να ελέγχεις αν τα δεδομένα πρίν τα αποθηκεύσεις είναι serializable και αν είναι του τύπου που θέλεις πριν τα εμφανίσεις.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
     
    Public Class Form1
    
        <Serializable()>
        Friend Class AClass
            Friend Sub New(ByVal format As String, ByVal image As Image)
                _Format = format
                _image = image
            End Sub
    
            Private _Format As String
            Friend ReadOnly Property Format As String
                Get
                    Return _Format
                End Get
            End Property
    
            Friend Property image As Image
        End Class
    
        Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
            Dim ColumnName As String = "OLE_OBJ"
            Dim TableName As String = "IMAGES"
            Dim con As New OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\Vangelis\Documents\MyDB.accdb")
            Dim image As Image = image.FromFile("C:\Users\Vangelis\Pictures\MyImage.bmp")
            Dim bytes() As Byte = Conversion(Of AClass).Serialize(New AClass("BMP", image))
            Dim command As OleDb.OleDbCommand
            Dim da As OleDb.OleDbDataAdapter
            Dim dt As DataTable
    
            con.Open()
    
            command = New OleDb.OleDbCommand("INSERT INTO " & TableName & " (" & ColumnName & ") VALUES (AByteArray)", con)
            command.Parameters.Add("AByteArray", OleDb.OleDbType.VarBinary).Value = bytes
            command.ExecuteNonQuery()
            command.Dispose()
    
            da = New OleDb.OleDbDataAdapter("SELECT TOP 1 " & ColumnName & " FROM " & TableName, con)
            dt = New DataTable
    
            da.Fill(dt)
            da.Dispose()
            con.Close()
    
            Dim a As AClass = Conversion(Of AClass).DeSerialize(DirectCast(dt.Rows(0).Item(ColumnName), Byte()))
            Me.BackgroundImage = a.image
    
            dt.Dispose()
        End Sub
    End Class
    
    Friend Class Conversion(Of AnyType) ' TODO AnyType Should be a serializable type only 
        Friend Shared Function Serialize(ByVal type As AnyType) As Byte()
            Dim memStream As New IO.MemoryStream
            Dim binF As New Runtime.Serialization.Formatters.Binary.BinaryFormatter
            Dim bytes() As Byte
    
            binF.Serialize(memStream, type)
            bytes = memStream.ToArray
            memStream.Close()
    
            Return bytes
        End Function
    
        Friend Shared Function DeSerialize(ByVal data As Byte()) As AnyType
            Dim memStream As New IO.MemoryStream(data)
            Dim binF As New Runtime.Serialization.Formatters.Binary.BinaryFormatter
            Dim any As AnyType
    
            any = DirectCast(binF.Deserialize(memStream), AnyType)
            memStream.Close()
    
            Return any
        End Function
    End Class

     

     

     

     

     

     

  •  01-11-2011, 21:15 67998 σε απάντηση της 67997

    Απ: VB.NET 2010 Εικόνα απο MS Access

    Πολύ ενδιαφέρων,

    θα τα δω και τα 2 :)


    Ευχαριστώ!!


  •  02-11-2011, 23:17 68009 σε απάντηση της 67998

    Απ: VB.NET 2010 Εικόνα απο MS Access

    Ναι! Δούλεψε :)


    Σας ευχαριστώ πολύ και τους 2 :)


  •  03-11-2011, 10:19 68010 σε απάντηση της 68009

    Απ: VB.NET 2010 Εικόνα απο MS Access

    Μια παρατήρηση σε σχέση με τον δεύτερο κώδικα.

    Βλέπω ότι μπορεί να αλλάξει μόνο το πρώτο row της βάσης δεδομένων, και δεν είμαι σίγουρος πως να το κάνω να αλλάζει αυτά που θέλω...

    δεν έχει πουθενά επιλογή για row(Νούμερο), ανταυτού έχει το 

    "SELECT TOP 1" &

    Αν μπορούσαμε να το κάνουμε με rows σώζομαι :)


  •  03-11-2011, 14:02 68016 σε απάντηση της 68010

    Απ: VB.NET 2010 Εικόνα απο MS Access

    Βγάλε το TOP, φέρτα όλα ή βάλε WHERE. Μετά κάνε loop ή άλλαξε αυτά που θέλεις. Το παρακάτω παράδειγμα φέρνει όλα τα Rows και τα Columns και γεμίζει ένα FlawLayoutPanel Control, δείχνωντας και το Format Property σαν Τίτλο. Εξέτασε και το lambda και αν θες απάντησε στην ερώτηση: "Τα paint events των pictureboxes γίνονται handle από το ίδιο sub ή από διαφορετικά;".

     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
     
        Private Sub DisplayImages()
            Dim ImageColumnName As String = "OLE_OBJ"
            Dim con As New OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\Vangelis\Documents\MyDB.accdb")
            Dim da As OleDb.OleDbDataAdapter
            Dim dt As DataTable
    
            con.Open()
    
            da = New OleDb.OleDbDataAdapter("SELECT * FROM IMAGES", con) ' Τώρα τα φέρνει όλα.
            dt = New DataTable
    
            da.Fill(dt)
            da.Dispose()
            con.Close()
    
            Me.FlowLayoutPanel1.Controls.Clear() ' Βάλε ένα FlowLayoutPanel control στην φόρμα σου
    
            Dim rows() As DataRow = dt.Select(ImageColumnName & " IS NOT NULL")
    
            For Each row As DataRow In rows
                Dim a As AClass = Conversion(Of AClass).DeSerialize(DirectCast(row.Item(ImageColumnName), Byte()))
                Dim picBox As New PictureBox With {
                                                    .SizeMode = PictureBoxSizeMode.Zoom,
                                                    .Width = 150,
                                                    .Height = 150,
                                                    .Image = a.image,
                                                    .Tag = a.Format,
                                                    .BackColor = Color.LightBlue
                                                  }
    
                AddHandler picBox.Paint, Sub(sender As Object, e As PaintEventArgs)
                                             e.Graphics.DrawString(
                                                  DirectCast(sender, PictureBox).Tag.ToString,
                                                  Me.Font,
                                                  Brushes.Black,
                                                  New Point(2, 3))
                                         End Sub
    
                Me.FlowLayoutPanel1.Controls.Add(picBox)
            Next
    
            dt.Dispose()
        End Sub

     

     

     

  •  04-11-2011, 21:23 68045 σε απάντηση της 68016

    Απ: VB.NET 2010 Εικόνα απο MS Access

    Πράγματι τα φέρνει όλα τώρα, αλλά το θέμα έιναι ότι δεν μπορώ να του πω να μου περάσει την τάδε φώτο στο .row(τάδε)

    Και αυτό είναι κάτι που πραγματικά χρειάζομαι

    Οπότε απότι καταλαβαίνω, πρέπει να σβήσουμε το "For Each row As DataRow In rows" και να το αντικαταστήσουμε με κάτι άλλο.

    Αλλά τι θα είναι αυτό το άλλο όμως?


Σελίδα 1 από 2 (30 εγγραφές)   1 2 >
Προβολή Τροφοδοσίας RSS με μορφή XML
Με χρήση του Community Server (Commercial Edition), από την Telligent Systems